package org.example.ResolvableType;

import org.springframework.core.ResolvableType;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Classname Test
 * @Description TODO
 * @Date 2021/1/21 3:23 下午
 * @Created by xiangjd
 */
public class Test {

    private HashMap<String, List<Object>> map;

    private HashMap<Integer, List<String>> myMap;



    @org.junit.Test
    public void test1() {

        //  java.lang.String
        ResolvableType resolvableType1 = ResolvableType.forClass(String.class);
        System.out.println(resolvableType1);
//  java.util.Map<?, ?>
        ResolvableType resolvableType2 = ResolvableType.forClass(Map.class, HashMap.class);
        System.out.println(resolvableType2);

    }

    @org.junit.Test
    public void test2() {
        User user = new User("张三");
        User user1 = new User("王五", "2323");
        Constructor<?> constructor = user.getClass().getConstructors()[0];
        Constructor<?> constructor0 = user1.getClass().getConstructors()[0];
        Constructor<?> constructor1 = user1.getClass().getConstructors()[1];
        System.out.println(constructor);
        System.out.println(constructor0);
        System.out.println(constructor1);
        // java.lang.String
        ResolvableType resolvableType = ResolvableType.forConstructorParameter(constructor, 0);
        System.out.println(resolvableType);

    }


    /**
     * 从成员属性中获取成员属性的类型信息
     *
     * @throws NoSuchFieldException
     */
    @org.junit.Test
    public void test3() throws NoSuchFieldException {

        Field field = getClass().getDeclaredField("map");
        // java.util.HashMap<java.lang.String, java.util.List<java.lang.Object>>
        ResolvableType resolvableType = ResolvableType.forField(field);
        System.out.println(resolvableType);
    }

    /**
     * 获取方法的参数类型信息。
     */
    @org.junit.Test
    public void test4() {
        User user = new User("张三");
        // setName(String)
        Method method = user.getClass().getMethods()[0];
        // java.lang.String
        ResolvableType resolvableType = ResolvableType.forMethodParameter(method, 0);
        System.out.println(resolvableType);
    }

    /**
     * 获取特定类型组成的数组形式。例如
     */
    @org.junit.Test
    public void test5(){
        ResolvableType resolvableType = ResolvableType.forClass(String.class);
// java.lang.String []
        ResolvableType arrayComponent = ResolvableType.forArrayComponent(resolvableType);
        System.out.println(arrayComponent);
    }

    /**
     * 当你需要利用反射获取 类实例、成员变量、方法的信息时就可以使用该操作类。
     * 它提供了获取基类、接口、Class对象、泛型类型等解析功能。例如我们可以从一个成员变量中可以获取：
     */
    @org.junit.Test
    public void test6() throws NoSuchFieldException {
        ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
        System.out.println(t.getSuperType());
        System.out.println(t.asMap());
        System.out.println(t.getGeneric(0).resolve());
        System.out.println(t.getGeneric(1).resolve());
        System.out.println(t.getGeneric(1));
        System.out.println(t.resolveGeneric(1, 0));
    }

}
